{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "c64d3134-4dec-44ff-9f5e-55b033c48edb",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "torch.manual_seed(0)\n",
    "torch.backends.cudnn.deterministic = False\n",
    "torch.backends.cudnn.benchmark = True\n",
    "\n",
    "import torchvision.models as models\n",
    "import torchvision.transforms as transforms\n",
    "import torchvision.datasets as datasets\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import torch.optim as optim\n",
    "from torch.autograd import Variable\n",
    "from torch.utils.data.dataset import Dataset\n",
    "import time\n",
    "import glob\n",
    "\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "from PIL import Image\n",
    "from PIL import ImageFile\n",
    "ImageFile.LOAD_TRUNCATED_IMAGES = True  # Globally allows loading truncated images\n",
    "\n",
    "from tqdm import tqdm_notebook"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "96943b0f-dcea-492c-ab3f-aef7d514c347",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "label_index = pd.read_csv(\"chinese_herbal_medicine.csv\")\n",
    "label_index = {k:v for v,k in label_index[\"category\"].to_dict().items()}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "01acdbde-f012-45db-ae94-beff97baa8f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_path = glob.glob('./train_set/*/*.jpg')\n",
    "np.random.shuffle(train_path)\n",
    "\n",
    "train_label = [label_index[x.split('/')[-2]] for x in train_path]\n",
    "\n",
    "test_path = glob.glob('./test_set/*.jpg')\n",
    "test_path.sort()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "cd793915-cb4d-46a1-8724-376d52c321f8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8525"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(train_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "a362d70b-cb53-4a9b-84d0-71d9141ad35b",
   "metadata": {},
   "outputs": [],
   "source": [
    "for path in train_path:\n",
    "    try:\n",
    "        img = Image.open(path).convert('RGB')\n",
    "        img.size\n",
    "    except:\n",
    "        train_path.remove(path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "55d1a9d3-0955-4fa6-95ae-bef086fe731a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8122"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(train_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "1a6a993b-1e33-46aa-b5d2-58df05f9feb4",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_label = [label_index[x.split('/')[-2]] for x in train_path]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "7c87b426-c326-4a3e-a3fe-3c69ccf2fa5b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['./test_set/006f490b-c352-414c-be06-0e14a39eb3ee.jpg',\n",
       " './test_set/007d7487-413d-4d11-9df1-1c40651f6428.jpg',\n",
       " './test_set/00b15eef-38c6-42e0-b1ed-5bbd34d9f20f.jpg',\n",
       " './test_set/00d3d2ea-2f66-40b7-b402-b2bcd36cf776.jpg',\n",
       " './test_set/01207b72-00c6-43c4-aa14-85e76c138022.jpg',\n",
       " './test_set/01385aa6-d1ca-4aa9-831f-a63ab7a02d66.jpg',\n",
       " './test_set/01631a84-1657-438e-94bc-3e5de97a7907.jpg',\n",
       " './test_set/0172672f-e02d-4809-a40c-b1ec16b25281.jpg',\n",
       " './test_set/0185e720-8592-44cb-8332-9e39c9e490ba.jpg',\n",
       " './test_set/018b4cd5-77ef-495d-a641-1df43725aa3b.jpg']"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_path[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "1c68dfcc-173e-47a9-b0a6-13c8336f4614",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "54"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(label_index)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "ab48904c-3f33-4299-a6ab-c44ee9a40670",
   "metadata": {},
   "outputs": [],
   "source": [
    "class AverageMeter(object):\n",
    "    \"\"\"Computes and stores the average and current value\"\"\"\n",
    "    def __init__(self, name, fmt=':f'):\n",
    "        self.name = name\n",
    "        self.fmt = fmt\n",
    "        self.reset()\n",
    "\n",
    "    def reset(self):\n",
    "        self.val = 0\n",
    "        self.avg = 0\n",
    "        self.sum = 0\n",
    "        self.count = 0\n",
    "\n",
    "    def update(self, val, n=1):\n",
    "        self.val = val\n",
    "        self.sum += val * n\n",
    "        self.count += n\n",
    "        self.avg = self.sum / self.count\n",
    "\n",
    "    def __str__(self):\n",
    "        fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})'\n",
    "        return fmtstr.format(**self.__dict__)\n",
    "\n",
    "class ProgressMeter(object):\n",
    "    def __init__(self, num_batches, *meters):\n",
    "        self.batch_fmtstr = self._get_batch_fmtstr(num_batches)\n",
    "        self.meters = meters\n",
    "        self.prefix = \"\"\n",
    "\n",
    "\n",
    "    def pr2int(self, batch):\n",
    "        entries = [self.prefix + self.batch_fmtstr.format(batch)]\n",
    "        entries += [str(meter) for meter in self.meters]\n",
    "        print('\\t'.join(entries))\n",
    "\n",
    "    def _get_batch_fmtstr(self, num_batches):\n",
    "        num_digits = len(str(num_batches // 1))\n",
    "        fmt = '{:' + str(num_digits) + 'd}'\n",
    "        return '[' + fmt + '/' + fmt.format(num_batches) + ']'\n",
    "\n",
    "def validate(val_loader, model, criterion):\n",
    "    batch_time = AverageMeter('Time', ':6.3f')\n",
    "    losses = AverageMeter('Loss', ':.4e')\n",
    "    top1 = AverageMeter('Acc@1', ':6.2f')\n",
    "    progress = ProgressMeter(len(val_loader), batch_time, losses, top1)\n",
    "\n",
    "    # switch to evaluate mode\n",
    "    model.eval()\n",
    "\n",
    "    with torch.no_grad():\n",
    "        end = time.time()\n",
    "        for i, (input, target) in tqdm_notebook(enumerate(val_loader), total=len(val_loader)):\n",
    "            input = input.cuda()\n",
    "            target = target.cuda()\n",
    "\n",
    "            # compute output\n",
    "            output = model(input)\n",
    "            loss = criterion(output, target)\n",
    "\n",
    "            # measure accuracy and record loss\n",
    "            acc = (output.argmax(1).view(-1) == target.float().view(-1)).float().mean() * 100\n",
    "            losses.update(loss.item(), input.size(0))\n",
    "            top1.update(acc, input.size(0))\n",
    "            # measure elapsed time\n",
    "            batch_time.update(time.time() - end)\n",
    "            end = time.time()\n",
    "\n",
    "        # TODO: this should also be done with the ProgressMeter\n",
    "        print(' * Acc@1 {top1.avg:.3f}'\n",
    "              .format(top1=top1))\n",
    "        return top1\n",
    "\n",
    "def predict(test_loader, model, tta=10):\n",
    "    # switch to evaluate mode\n",
    "    model.eval()\n",
    "    \n",
    "    test_pred_tta = None\n",
    "    for _ in range(tta):\n",
    "        test_pred = []\n",
    "        with torch.no_grad():\n",
    "            end = time.time()\n",
    "            for i, (input, target) in tqdm_notebook(enumerate(test_loader), total=len(test_loader)):\n",
    "                input = input.cuda()\n",
    "                target = target.cuda()\n",
    "\n",
    "                # compute output\n",
    "                output = model(input)\n",
    "                output = F.softmax(output, dim=1)\n",
    "                output = output.data.cpu().numpy()\n",
    "\n",
    "                test_pred.append(output)\n",
    "        test_pred = np.vstack(test_pred)\n",
    "    \n",
    "        if test_pred_tta is None:\n",
    "            test_pred_tta = test_pred\n",
    "        else:\n",
    "            test_pred_tta += test_pred\n",
    "    \n",
    "    return test_pred_tta\n",
    "\n",
    "def train(train_loader, model, criterion, optimizer, epoch):\n",
    "    batch_time = AverageMeter('Time', ':6.3f')\n",
    "    losses = AverageMeter('Loss', ':.4e')\n",
    "    top1 = AverageMeter('Acc@1', ':6.2f')\n",
    "    progress = ProgressMeter(len(train_loader), batch_time, losses, top1)\n",
    "\n",
    "    # switch to train mode\n",
    "    model.train()\n",
    "\n",
    "    end = time.time()\n",
    "    for i, (input, target) in enumerate(train_loader):\n",
    "        input = input.cuda(non_blocking=True)\n",
    "        target = target.cuda(non_blocking=True)\n",
    "\n",
    "        # compute output\n",
    "        output = model(input)\n",
    "        loss = criterion(output, target)\n",
    "\n",
    "        # measure accuracy and record loss\n",
    "        losses.update(loss.item(), input.size(0))\n",
    "\n",
    "        acc = (output.argmax(1).view(-1) == target.float().view(-1)).float().mean() * 100\n",
    "        top1.update(acc, input.size(0))\n",
    "\n",
    "        # compute gradient and do SGD step\n",
    "        optimizer.zero_grad()\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "\n",
    "        # measure elapsed time\n",
    "        batch_time.update(time.time() - end)\n",
    "        end = time.time()\n",
    "\n",
    "        if i % 100 == 0:\n",
    "            progress.pr2int(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "id": "dde84a60-5939-4b69-b0a9-bb43773186b9",
   "metadata": {},
   "outputs": [],
   "source": [
    "class XFDataset(Dataset):\n",
    "    def __init__(self, img_path, img_label, transform=None):\n",
    "        self.img_path = img_path\n",
    "        self.img_label = img_label\n",
    "        \n",
    "        if transform is not None:\n",
    "            self.transform = transform\n",
    "        else:\n",
    "            self.transform = None\n",
    "    \n",
    "    def __getitem__(self, index):\n",
    "        try:\n",
    "            img = Image.open(self.img_path[index]).convert('RGB')\n",
    "        except:\n",
    "            img = Image.new('RGB', (224, 224), color='white')\n",
    "\n",
    "        label = torch.from_numpy(np.array(self.img_label[index]))\n",
    "        if self.transform is not None:\n",
    "            img = self.transform(img)\n",
    "        \n",
    "        return img, label\n",
    "    \n",
    "    def __len__(self):\n",
    "        return len(self.img_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "id": "aad4267f-b007-48a4-8e06-cf89df9b9f2f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'\n",
    "\n",
    "import timm\n",
    "model = timm.create_model('resnet18', pretrained=True, num_classes=len(label_index))\n",
    "model = model.cuda()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "id": "abc0c12c-5cdd-42fd-bfd6-9027431e46e2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch:  0\n",
      "[  0/763]\tTime  0.280 ( 0.280)\tLoss 4.0691e+00 (4.0691e+00)\tAcc@1   0.00 (  0.00)\n",
      "[100/763]\tTime  0.028 ( 0.029)\tLoss 3.3308e+00 (3.7872e+00)\tAcc@1  10.00 (  7.43)\n",
      "[200/763]\tTime  0.120 ( 0.029)\tLoss 2.8703e+00 (3.4719e+00)\tAcc@1  30.00 ( 14.08)\n",
      "[300/763]\tTime  0.171 ( 0.028)\tLoss 3.0330e+00 (3.2177e+00)\tAcc@1  30.00 ( 20.47)\n",
      "[400/763]\tTime  0.025 ( 0.028)\tLoss 1.8518e+00 (3.0140e+00)\tAcc@1  50.00 ( 24.14)\n",
      "[500/763]\tTime  0.025 ( 0.028)\tLoss 1.8098e+00 (2.8778e+00)\tAcc@1  70.00 ( 27.25)\n",
      "[600/763]\tTime  0.028 ( 0.027)\tLoss 2.1014e+00 (2.7492e+00)\tAcc@1  60.00 ( 30.25)\n",
      "[700/763]\tTime  0.026 ( 0.027)\tLoss 2.4719e+00 (2.6548e+00)\tAcc@1  30.00 ( 32.52)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_3559365/1274669909.py:52: TqdmDeprecationWarning: This function will be removed in tqdm==5.0.0\n",
      "Please use `tqdm.notebook.tqdm` instead of `tqdm.tqdm_notebook`\n",
      "  for i, (input, target) in tqdm_notebook(enumerate(val_loader), total=len(val_loader)):\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "430960fea825468cba23ae2ce8e986b1",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 51.200\n",
      "Epoch:  1\n",
      "[  0/763]\tTime  0.268 ( 0.268)\tLoss 1.3543e+00 (1.3543e+00)\tAcc@1  60.00 ( 60.00)\n",
      "[100/763]\tTime  0.022 ( 0.032)\tLoss 1.6205e+00 (1.8530e+00)\tAcc@1  50.00 ( 49.50)\n",
      "[200/763]\tTime  0.028 ( 0.030)\tLoss 1.0775e+00 (1.8112e+00)\tAcc@1  70.00 ( 51.04)\n",
      "[300/763]\tTime  0.024 ( 0.029)\tLoss 1.0627e+00 (1.7675e+00)\tAcc@1  90.00 ( 52.19)\n",
      "[400/763]\tTime  0.024 ( 0.029)\tLoss 1.8049e+00 (1.7593e+00)\tAcc@1  40.00 ( 52.69)\n",
      "[500/763]\tTime  0.027 ( 0.029)\tLoss 1.3464e+00 (1.7254e+00)\tAcc@1  40.00 ( 53.43)\n",
      "[600/763]\tTime  0.028 ( 0.028)\tLoss 2.3905e+00 (1.7023e+00)\tAcc@1  40.00 ( 53.76)\n",
      "[700/763]\tTime  0.024 ( 0.028)\tLoss 1.9786e+00 (1.6916e+00)\tAcc@1  60.00 ( 54.14)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "6372098e449e41cdb282e090a443998c",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 60.000\n",
      "Epoch:  2\n",
      "[  0/763]\tTime  0.257 ( 0.257)\tLoss 1.2047e+00 (1.2047e+00)\tAcc@1  70.00 ( 70.00)\n",
      "[100/763]\tTime  0.027 ( 0.029)\tLoss 1.5879e+00 (1.3169e+00)\tAcc@1  50.00 ( 64.46)\n",
      "[200/763]\tTime  0.030 ( 0.028)\tLoss 9.2711e-01 (1.3696e+00)\tAcc@1  70.00 ( 63.48)\n",
      "[300/763]\tTime  0.026 ( 0.028)\tLoss 1.3268e+00 (1.3503e+00)\tAcc@1  70.00 ( 63.65)\n",
      "[400/763]\tTime  0.025 ( 0.027)\tLoss 1.5782e+00 (1.3623e+00)\tAcc@1  60.00 ( 63.37)\n",
      "[500/763]\tTime  0.024 ( 0.027)\tLoss 1.2918e+00 (1.3691e+00)\tAcc@1  60.00 ( 63.29)\n",
      "[600/763]\tTime  0.023 ( 0.027)\tLoss 7.2814e-01 (1.3826e+00)\tAcc@1  80.00 ( 62.71)\n",
      "[700/763]\tTime  0.033 ( 0.027)\tLoss 1.4433e+00 (1.3761e+00)\tAcc@1  60.00 ( 62.80)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "fa95857a38c547298bd85cd016f5b04e",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 64.600\n",
      "Epoch:  3\n",
      "[  0/763]\tTime  0.444 ( 0.444)\tLoss 9.5304e-01 (9.5304e-01)\tAcc@1  70.00 ( 70.00)\n",
      "[100/763]\tTime  0.025 ( 0.030)\tLoss 8.8548e-01 (1.1500e+00)\tAcc@1  70.00 ( 68.02)\n",
      "[200/763]\tTime  0.025 ( 0.028)\tLoss 8.4484e-01 (1.1028e+00)\tAcc@1  80.00 ( 69.25)\n",
      "[300/763]\tTime  0.025 ( 0.028)\tLoss 1.5266e+00 (1.0951e+00)\tAcc@1  60.00 ( 69.50)\n",
      "[400/763]\tTime  0.026 ( 0.027)\tLoss 1.5764e+00 (1.0960e+00)\tAcc@1  40.00 ( 69.73)\n",
      "[500/763]\tTime  0.026 ( 0.027)\tLoss 1.9737e-01 (1.0938e+00)\tAcc@1 100.00 ( 69.80)\n",
      "[600/763]\tTime  0.026 ( 0.027)\tLoss 9.2997e-01 (1.0865e+00)\tAcc@1  80.00 ( 70.07)\n",
      "[700/763]\tTime  0.024 ( 0.027)\tLoss 7.6612e-01 (1.0878e+00)\tAcc@1  80.00 ( 70.07)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "8770615667704c9b89b92bafae5e7e95",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 68.600\n",
      "Epoch:  4\n",
      "[  0/763]\tTime  0.310 ( 0.310)\tLoss 7.7532e-01 (7.7532e-01)\tAcc@1  80.00 ( 80.00)\n",
      "[100/763]\tTime  0.022 ( 0.033)\tLoss 4.6986e-01 (9.1653e-01)\tAcc@1  80.00 ( 74.55)\n",
      "[200/763]\tTime  0.028 ( 0.030)\tLoss 1.2301e+00 (9.4135e-01)\tAcc@1  80.00 ( 73.88)\n",
      "[300/763]\tTime  0.026 ( 0.029)\tLoss 3.9588e-01 (9.5421e-01)\tAcc@1 100.00 ( 73.75)\n",
      "[400/763]\tTime  0.023 ( 0.028)\tLoss 9.7661e-01 (9.3484e-01)\tAcc@1  60.00 ( 73.94)\n",
      "[500/763]\tTime  0.025 ( 0.028)\tLoss 6.8852e-01 (9.2715e-01)\tAcc@1  80.00 ( 74.09)\n",
      "[600/763]\tTime  0.026 ( 0.027)\tLoss 7.5543e-01 (9.2445e-01)\tAcc@1  80.00 ( 74.16)\n",
      "[700/763]\tTime  0.025 ( 0.028)\tLoss 7.9635e-01 (9.1969e-01)\tAcc@1  70.00 ( 74.37)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "390dfdceab514f8dbda8381b5352d5a9",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 67.200\n",
      "Epoch:  5\n",
      "[  0/763]\tTime  0.262 ( 0.262)\tLoss 9.1862e-01 (9.1862e-01)\tAcc@1  70.00 ( 70.00)\n",
      "[100/763]\tTime  0.025 ( 0.035)\tLoss 6.2567e-01 (8.1192e-01)\tAcc@1  80.00 ( 77.43)\n",
      "[200/763]\tTime  0.024 ( 0.031)\tLoss 1.1895e+00 (8.2263e-01)\tAcc@1  70.00 ( 76.82)\n",
      "[300/763]\tTime  0.026 ( 0.030)\tLoss 6.8614e-01 (8.0490e-01)\tAcc@1  80.00 ( 76.84)\n",
      "[400/763]\tTime  0.027 ( 0.029)\tLoss 5.2197e-01 (8.1178e-01)\tAcc@1  80.00 ( 76.76)\n",
      "[500/763]\tTime  0.024 ( 0.028)\tLoss 1.1788e-01 (8.0821e-01)\tAcc@1 100.00 ( 76.67)\n",
      "[600/763]\tTime  0.026 ( 0.028)\tLoss 6.6387e-01 (8.0427e-01)\tAcc@1  90.00 ( 76.84)\n",
      "[700/763]\tTime  0.022 ( 0.028)\tLoss 3.3604e-01 (8.1190e-01)\tAcc@1  80.00 ( 76.69)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "5d528d1ba9cb476988d4802276f7d443",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 75.800\n",
      "Epoch:  6\n",
      "[  0/763]\tTime  0.422 ( 0.422)\tLoss 6.0120e-01 (6.0120e-01)\tAcc@1  80.00 ( 80.00)\n",
      "[100/763]\tTime  0.028 ( 0.033)\tLoss 5.2314e-01 (6.3812e-01)\tAcc@1  80.00 ( 81.78)\n",
      "[200/763]\tTime  0.026 ( 0.030)\tLoss 5.8560e-01 (6.9037e-01)\tAcc@1  80.00 ( 80.45)\n",
      "[300/763]\tTime  0.022 ( 0.030)\tLoss 5.4326e-01 (6.8081e-01)\tAcc@1  80.00 ( 81.10)\n",
      "[400/763]\tTime  0.025 ( 0.029)\tLoss 8.9760e-01 (6.7259e-01)\tAcc@1  80.00 ( 81.47)\n",
      "[500/763]\tTime  0.022 ( 0.029)\tLoss 3.6175e-01 (6.7185e-01)\tAcc@1  90.00 ( 81.12)\n",
      "[600/763]\tTime  0.024 ( 0.029)\tLoss 8.3030e-01 (6.9241e-01)\tAcc@1  80.00 ( 80.37)\n",
      "[700/763]\tTime  0.025 ( 0.029)\tLoss 1.3354e+00 (6.9447e-01)\tAcc@1  60.00 ( 80.40)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "702d98a27ba440f7a241d683bb1ac89b",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 69.200\n",
      "Epoch:  7\n",
      "[  0/763]\tTime  0.280 ( 0.280)\tLoss 6.7122e-01 (6.7122e-01)\tAcc@1  80.00 ( 80.00)\n",
      "[100/763]\tTime  0.028 ( 0.028)\tLoss 3.7805e-01 (5.7931e-01)\tAcc@1  90.00 ( 83.17)\n",
      "[200/763]\tTime  0.025 ( 0.027)\tLoss 8.5391e-01 (5.5207e-01)\tAcc@1  70.00 ( 83.58)\n",
      "[300/763]\tTime  0.025 ( 0.029)\tLoss 1.2158e+00 (5.5693e-01)\tAcc@1  60.00 ( 83.59)\n",
      "[400/763]\tTime  0.026 ( 0.028)\tLoss 1.3337e+00 (5.4136e-01)\tAcc@1  90.00 ( 83.94)\n",
      "[500/763]\tTime  0.032 ( 0.028)\tLoss 5.8981e-01 (5.4663e-01)\tAcc@1  90.00 ( 83.77)\n",
      "[600/763]\tTime  0.025 ( 0.028)\tLoss 2.8530e-01 (5.5021e-01)\tAcc@1  90.00 ( 83.69)\n",
      "[700/763]\tTime  0.026 ( 0.028)\tLoss 1.0885e+00 (5.4219e-01)\tAcc@1  80.00 ( 84.11)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "110790b69f7847c7872311e6b7a81531",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 76.200\n",
      "Epoch:  8\n",
      "[  0/763]\tTime  0.266 ( 0.266)\tLoss 7.4283e-01 (7.4283e-01)\tAcc@1  80.00 ( 80.00)\n",
      "[100/763]\tTime  0.026 ( 0.028)\tLoss 1.7537e-01 (5.0845e-01)\tAcc@1 100.00 ( 84.65)\n",
      "[200/763]\tTime  0.022 ( 0.028)\tLoss 4.0385e-01 (4.9886e-01)\tAcc@1  90.00 ( 84.98)\n",
      "[300/763]\tTime  0.025 ( 0.028)\tLoss 8.5943e-01 (4.7970e-01)\tAcc@1  60.00 ( 85.91)\n",
      "[400/763]\tTime  0.030 ( 0.028)\tLoss 3.4421e-01 (4.6605e-01)\tAcc@1  90.00 ( 86.63)\n",
      "[500/763]\tTime  0.025 ( 0.028)\tLoss 9.0612e-01 (4.7277e-01)\tAcc@1  70.00 ( 86.27)\n",
      "[600/763]\tTime  0.029 ( 0.028)\tLoss 3.9275e-01 (4.8043e-01)\tAcc@1  90.00 ( 85.82)\n",
      "[700/763]\tTime  0.026 ( 0.028)\tLoss 4.0308e-01 (4.8174e-01)\tAcc@1  90.00 ( 85.91)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a5256df8b6a940bb87c1325778fc3e66",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 75.200\n",
      "Epoch:  9\n",
      "[  0/763]\tTime  0.350 ( 0.350)\tLoss 1.4037e-01 (1.4037e-01)\tAcc@1 100.00 (100.00)\n",
      "[100/763]\tTime  0.024 ( 0.031)\tLoss 1.6095e-01 (4.1281e-01)\tAcc@1 100.00 ( 88.22)\n",
      "[200/763]\tTime  0.032 ( 0.029)\tLoss 5.3435e-01 (4.1404e-01)\tAcc@1  70.00 ( 87.76)\n",
      "[300/763]\tTime  0.022 ( 0.028)\tLoss 1.6529e-01 (4.0936e-01)\tAcc@1 100.00 ( 88.07)\n",
      "[400/763]\tTime  0.031 ( 0.028)\tLoss 1.6344e+00 (4.2420e-01)\tAcc@1  60.00 ( 87.81)\n",
      "[500/763]\tTime  0.024 ( 0.028)\tLoss 3.1651e-01 (4.3008e-01)\tAcc@1  90.00 ( 87.45)\n",
      "[600/763]\tTime  0.027 ( 0.027)\tLoss 2.1770e-01 (4.3468e-01)\tAcc@1 100.00 ( 87.22)\n",
      "[700/763]\tTime  0.023 ( 0.027)\tLoss 4.5741e-01 (4.3364e-01)\tAcc@1  80.00 ( 87.12)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "8a58510fad3045498a9b49c41a7bdadb",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 73.400\n",
      "Epoch:  10\n",
      "[  0/763]\tTime  0.272 ( 0.272)\tLoss 6.8335e-01 (6.8335e-01)\tAcc@1  80.00 ( 80.00)\n",
      "[100/763]\tTime  0.027 ( 0.029)\tLoss 9.9385e-01 (3.8495e-01)\tAcc@1  70.00 ( 88.81)\n",
      "[200/763]\tTime  0.027 ( 0.028)\tLoss 3.7084e-01 (3.6849e-01)\tAcc@1  90.00 ( 88.91)\n",
      "[300/763]\tTime  0.030 ( 0.028)\tLoss 2.3021e-01 (4.0337e-01)\tAcc@1 100.00 ( 87.91)\n",
      "[400/763]\tTime  0.034 ( 0.028)\tLoss 7.4769e-01 (4.1197e-01)\tAcc@1  80.00 ( 87.66)\n",
      "[500/763]\tTime  0.030 ( 0.028)\tLoss 4.9439e-03 (4.0283e-01)\tAcc@1 100.00 ( 88.18)\n",
      "[600/763]\tTime  0.038 ( 0.028)\tLoss 1.1385e-01 (4.0294e-01)\tAcc@1  90.00 ( 88.02)\n",
      "[700/763]\tTime  0.026 ( 0.028)\tLoss 1.7387e-01 (4.0155e-01)\tAcc@1  90.00 ( 87.96)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "597b50ab9903444e9d0e4e14a2c9a056",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 76.800\n",
      "Epoch:  11\n",
      "[  0/763]\tTime  0.287 ( 0.287)\tLoss 8.6691e-02 (8.6691e-02)\tAcc@1 100.00 (100.00)\n",
      "[100/763]\tTime  0.159 ( 0.032)\tLoss 5.4101e-01 (3.1472e-01)\tAcc@1  70.00 ( 90.20)\n",
      "[200/763]\tTime  0.028 ( 0.029)\tLoss 2.7388e-01 (2.9242e-01)\tAcc@1  90.00 ( 91.09)\n",
      "[300/763]\tTime  0.024 ( 0.028)\tLoss 1.4696e-01 (3.0125e-01)\tAcc@1 100.00 ( 91.00)\n",
      "[400/763]\tTime  0.025 ( 0.028)\tLoss 1.4508e-01 (3.0089e-01)\tAcc@1 100.00 ( 90.95)\n",
      "[500/763]\tTime  0.023 ( 0.028)\tLoss 4.0768e-01 (2.9382e-01)\tAcc@1  90.00 ( 91.12)\n",
      "[600/763]\tTime  0.026 ( 0.027)\tLoss 2.6833e-01 (2.9592e-01)\tAcc@1  90.00 ( 91.10)\n",
      "[700/763]\tTime  0.024 ( 0.027)\tLoss 3.5922e-01 (3.0312e-01)\tAcc@1  80.00 ( 91.00)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "4cc28660f4e04d0980f44ff7f0707b5f",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 77.800\n",
      "Epoch:  12\n",
      "[  0/763]\tTime  0.307 ( 0.307)\tLoss 5.9140e-02 (5.9140e-02)\tAcc@1 100.00 (100.00)\n",
      "[100/763]\tTime  0.027 ( 0.030)\tLoss 3.6131e-01 (2.4005e-01)\tAcc@1  90.00 ( 93.07)\n",
      "[200/763]\tTime  0.024 ( 0.028)\tLoss 3.1794e-01 (2.5326e-01)\tAcc@1  90.00 ( 92.39)\n",
      "[300/763]\tTime  0.024 ( 0.028)\tLoss 4.9144e-02 (2.6090e-01)\tAcc@1 100.00 ( 92.29)\n",
      "[400/763]\tTime  0.029 ( 0.028)\tLoss 5.4448e-01 (2.7511e-01)\tAcc@1  90.00 ( 91.67)\n",
      "[500/763]\tTime  0.028 ( 0.028)\tLoss 3.6184e-01 (2.7062e-01)\tAcc@1  80.00 ( 91.68)\n",
      "[600/763]\tTime  0.031 ( 0.028)\tLoss 2.7262e-01 (2.7568e-01)\tAcc@1  90.00 ( 91.55)\n",
      "[700/763]\tTime  0.027 ( 0.028)\tLoss 4.7171e-01 (2.7443e-01)\tAcc@1  90.00 ( 91.73)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "06ae884a24e04574af80c9b0f48c7083",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 76.600\n",
      "Epoch:  13\n",
      "[  0/763]\tTime  0.258 ( 0.258)\tLoss 1.9827e-01 (1.9827e-01)\tAcc@1  90.00 ( 90.00)\n",
      "[100/763]\tTime  0.029 ( 0.031)\tLoss 2.4568e-01 (2.4959e-01)\tAcc@1  90.00 ( 92.67)\n",
      "[200/763]\tTime  0.027 ( 0.029)\tLoss 4.3320e-01 (2.3579e-01)\tAcc@1  90.00 ( 93.18)\n",
      "[300/763]\tTime  0.028 ( 0.028)\tLoss 7.2648e-02 (2.4254e-01)\tAcc@1 100.00 ( 92.82)\n",
      "[400/763]\tTime  0.024 ( 0.029)\tLoss 5.5048e-03 (2.4367e-01)\tAcc@1 100.00 ( 92.74)\n",
      "[500/763]\tTime  0.023 ( 0.028)\tLoss 5.0476e-01 (2.4983e-01)\tAcc@1  90.00 ( 92.61)\n",
      "[600/763]\tTime  0.029 ( 0.028)\tLoss 1.1394e+00 (2.5612e-01)\tAcc@1  80.00 ( 92.48)\n",
      "[700/763]\tTime  0.021 ( 0.028)\tLoss 7.2782e-02 (2.6730e-01)\tAcc@1 100.00 ( 92.23)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "8ca1b3c3b0fd482cbeaea14b15f477e5",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 78.800\n",
      "Epoch:  14\n",
      "[  0/763]\tTime  0.284 ( 0.284)\tLoss 9.3699e-02 (9.3699e-02)\tAcc@1 100.00 (100.00)\n",
      "[100/763]\tTime  0.028 ( 0.031)\tLoss 7.2797e-01 (1.9805e-01)\tAcc@1  70.00 ( 94.26)\n",
      "[200/763]\tTime  0.030 ( 0.029)\tLoss 2.1312e-01 (2.1036e-01)\tAcc@1 100.00 ( 94.28)\n",
      "[300/763]\tTime  0.024 ( 0.029)\tLoss 7.0070e-02 (2.0815e-01)\tAcc@1 100.00 ( 94.12)\n",
      "[400/763]\tTime  0.025 ( 0.029)\tLoss 1.4800e-01 (2.2250e-01)\tAcc@1 100.00 ( 93.72)\n",
      "[500/763]\tTime  0.056 ( 0.028)\tLoss 1.8086e-01 (2.2117e-01)\tAcc@1 100.00 ( 93.69)\n",
      "[600/763]\tTime  0.028 ( 0.028)\tLoss 4.2974e-01 (2.1985e-01)\tAcc@1  80.00 ( 93.69)\n",
      "[700/763]\tTime  0.022 ( 0.028)\tLoss 3.4819e-01 (2.1937e-01)\tAcc@1  80.00 ( 93.61)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "80372cdf83b84b9bad4e6fcf81776c93",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 77.800\n",
      "Epoch:  15\n",
      "[  0/763]\tTime  0.304 ( 0.304)\tLoss 3.2110e-02 (3.2110e-02)\tAcc@1 100.00 (100.00)\n",
      "[100/763]\tTime  0.026 ( 0.029)\tLoss 8.8859e-02 (1.5692e-01)\tAcc@1 100.00 ( 95.15)\n",
      "[200/763]\tTime  0.026 ( 0.028)\tLoss 9.6691e-02 (1.6744e-01)\tAcc@1 100.00 ( 94.93)\n",
      "[300/763]\tTime  0.024 ( 0.027)\tLoss 2.8211e-01 (1.7563e-01)\tAcc@1  90.00 ( 94.78)\n",
      "[400/763]\tTime  0.024 ( 0.028)\tLoss 4.5133e-02 (1.8172e-01)\tAcc@1 100.00 ( 94.59)\n",
      "[500/763]\tTime  0.025 ( 0.028)\tLoss 1.0679e-01 (1.7807e-01)\tAcc@1 100.00 ( 94.81)\n",
      "[600/763]\tTime  0.025 ( 0.028)\tLoss 1.4572e-01 (1.7651e-01)\tAcc@1  90.00 ( 94.81)\n",
      "[700/763]\tTime  0.025 ( 0.028)\tLoss 1.7495e-01 (1.8202e-01)\tAcc@1 100.00 ( 94.66)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b46aac5ad45941ccab15468505051780",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 79.400\n",
      "Epoch:  16\n",
      "[  0/763]\tTime  0.262 ( 0.262)\tLoss 4.0298e-02 (4.0298e-02)\tAcc@1 100.00 (100.00)\n",
      "[100/763]\tTime  0.025 ( 0.031)\tLoss 1.3506e-01 (1.3146e-01)\tAcc@1 100.00 ( 95.74)\n",
      "[200/763]\tTime  0.023 ( 0.028)\tLoss 1.3349e-01 (1.4464e-01)\tAcc@1  90.00 ( 95.42)\n",
      "[300/763]\tTime  0.024 ( 0.028)\tLoss 2.0964e-01 (1.4551e-01)\tAcc@1  90.00 ( 95.42)\n",
      "[400/763]\tTime  0.025 ( 0.028)\tLoss 3.8734e-01 (1.5165e-01)\tAcc@1  90.00 ( 95.21)\n",
      "[500/763]\tTime  0.028 ( 0.028)\tLoss 1.2457e-01 (1.6077e-01)\tAcc@1  90.00 ( 94.99)\n",
      "[600/763]\tTime  0.022 ( 0.028)\tLoss 1.4505e-01 (1.6493e-01)\tAcc@1  90.00 ( 94.84)\n",
      "[700/763]\tTime  0.025 ( 0.028)\tLoss 1.1527e-01 (1.6684e-01)\tAcc@1  90.00 ( 94.86)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "5c20cc3721c74354b6e9f148e7e5714c",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 78.800\n",
      "Epoch:  17\n",
      "[  0/763]\tTime  0.261 ( 0.261)\tLoss 2.4832e-02 (2.4832e-02)\tAcc@1 100.00 (100.00)\n",
      "[100/763]\tTime  0.026 ( 0.029)\tLoss 5.6986e-02 (1.2706e-01)\tAcc@1 100.00 ( 97.13)\n",
      "[200/763]\tTime  0.025 ( 0.029)\tLoss 2.1062e-01 (1.3177e-01)\tAcc@1  90.00 ( 96.17)\n",
      "[300/763]\tTime  0.027 ( 0.028)\tLoss 1.4096e-01 (1.4132e-01)\tAcc@1 100.00 ( 95.65)\n",
      "[400/763]\tTime  0.026 ( 0.027)\tLoss 1.2485e-01 (1.4123e-01)\tAcc@1  90.00 ( 95.49)\n",
      "[500/763]\tTime  0.029 ( 0.027)\tLoss 9.0011e-02 (1.4930e-01)\tAcc@1 100.00 ( 95.31)\n",
      "[600/763]\tTime  0.021 ( 0.028)\tLoss 3.6787e-01 (1.5649e-01)\tAcc@1  90.00 ( 94.99)\n",
      "[700/763]\tTime  0.025 ( 0.028)\tLoss 2.2477e-01 (1.5583e-01)\tAcc@1  90.00 ( 95.05)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "acda6c14eef64f6da699f7eaf667862d",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 77.200\n",
      "Epoch:  18\n",
      "[  0/763]\tTime  0.291 ( 0.291)\tLoss 1.8693e-01 (1.8693e-01)\tAcc@1  90.00 ( 90.00)\n",
      "[100/763]\tTime  0.025 ( 0.031)\tLoss 1.7509e-01 (1.9842e-01)\tAcc@1  90.00 ( 93.96)\n",
      "[200/763]\tTime  0.025 ( 0.030)\tLoss 3.7665e-01 (1.6763e-01)\tAcc@1  80.00 ( 94.88)\n",
      "[300/763]\tTime  0.026 ( 0.029)\tLoss 2.0604e-02 (1.6482e-01)\tAcc@1 100.00 ( 95.12)\n",
      "[400/763]\tTime  0.025 ( 0.028)\tLoss 2.3494e-02 (1.6603e-01)\tAcc@1 100.00 ( 95.06)\n",
      "[500/763]\tTime  0.025 ( 0.028)\tLoss 4.0113e-02 (1.5512e-01)\tAcc@1 100.00 ( 95.49)\n",
      "[600/763]\tTime  0.020 ( 0.028)\tLoss 1.6110e-01 (1.5024e-01)\tAcc@1 100.00 ( 95.76)\n",
      "[700/763]\tTime  0.027 ( 0.028)\tLoss 7.6947e-02 (1.5441e-01)\tAcc@1 100.00 ( 95.61)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "1a390b352e244ab3aa9fb67debdcb357",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 77.600\n",
      "Epoch:  19\n",
      "[  0/763]\tTime  0.311 ( 0.311)\tLoss 2.1786e-01 (2.1786e-01)\tAcc@1  90.00 ( 90.00)\n",
      "[100/763]\tTime  0.029 ( 0.030)\tLoss 7.6430e-02 (1.2448e-01)\tAcc@1 100.00 ( 96.24)\n",
      "[200/763]\tTime  0.031 ( 0.028)\tLoss 5.2715e-03 (1.0296e-01)\tAcc@1 100.00 ( 97.26)\n",
      "[300/763]\tTime  0.023 ( 0.028)\tLoss 6.3700e-02 (1.0464e-01)\tAcc@1 100.00 ( 97.21)\n",
      "[400/763]\tTime  0.025 ( 0.028)\tLoss 2.3657e-03 (1.0401e-01)\tAcc@1 100.00 ( 97.21)\n",
      "[500/763]\tTime  0.025 ( 0.028)\tLoss 4.1642e-02 (1.0472e-01)\tAcc@1 100.00 ( 97.11)\n",
      "[600/763]\tTime  0.025 ( 0.028)\tLoss 2.3447e-02 (1.0926e-01)\tAcc@1 100.00 ( 96.94)\n",
      "[700/763]\tTime  0.029 ( 0.028)\tLoss 1.1835e-01 (1.1077e-01)\tAcc@1  90.00 ( 96.78)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "4dd59273c94a41feabb5e36b4dede913",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/50 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " * Acc@1 78.200\n"
     ]
    }
   ],
   "source": [
    "train_loader = torch.utils.data.DataLoader(\n",
    "    XFDataset(train_path[:-500], train_label[:-500], \n",
    "            transforms.Compose([\n",
    "                        transforms.Resize((256, 256)),\n",
    "                        transforms.RandomHorizontalFlip(),\n",
    "                        transforms.RandomVerticalFlip(),\n",
    "                        transforms.ToTensor(),\n",
    "                        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n",
    "        ])\n",
    "    ), batch_size=10, shuffle=True, num_workers=4, pin_memory=True\n",
    ")\n",
    "\n",
    "val_loader = torch.utils.data.DataLoader(\n",
    "    XFDataset(train_path[-500:], train_label[-500:], \n",
    "            transforms.Compose([\n",
    "                        transforms.Resize((256, 256)),\n",
    "                        transforms.ToTensor(),\n",
    "                        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n",
    "        ])\n",
    "    ), batch_size=10, shuffle=False, num_workers=4, pin_memory=True\n",
    ")\n",
    "\n",
    "criterion = nn.CrossEntropyLoss().cuda()\n",
    "optimizer = torch.optim.Adam(model.parameters(), 0.001)\n",
    "scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=4, gamma=0.85)\n",
    "best_acc = 0.0\n",
    "for epoch in range(20):\n",
    "    scheduler.step()\n",
    "    print('Epoch: ', epoch)\n",
    "\n",
    "    train(train_loader, model, criterion, optimizer, epoch)\n",
    "    val_acc = validate(val_loader, model, criterion)\n",
    "    \n",
    "    if val_acc.avg.item() > best_acc:\n",
    "        best_acc = round(val_acc.avg.item(), 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "id": "a27f9b82-4c72-46fb-9579-15eae0fed16f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8122"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(train_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "id": "41e86d06-e364-4e3f-8631-c2f3c0722e35",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_3559365/1274669909.py:82: TqdmDeprecationWarning: This function will be removed in tqdm==5.0.0\n",
      "Please use `tqdm.notebook.tqdm` instead of `tqdm.tqdm_notebook`\n",
      "  for i, (input, target) in tqdm_notebook(enumerate(test_loader), total=len(test_loader)):\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "bcf66ab1f5ee47af8dda36f52a866811",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/46 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "test_path = list(\"./test_set/\" + pd.read_csv(\"example_A.csv\")[\"ImageID\"])\n",
    "\n",
    "test_loader = torch.utils.data.DataLoader(\n",
    "    XFDataset(test_path, [0] * len(test_path), \n",
    "            transforms.Compose([\n",
    "                        transforms.Resize((256, 256)),\n",
    "                        transforms.ToTensor(),\n",
    "                        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n",
    "        ])\n",
    "    ), batch_size=40, shuffle=False, num_workers=4, pin_memory=True\n",
    ")\n",
    "\n",
    "val_label = pd.DataFrame()\n",
    "val_label['ImageID'] = [x.split('/')[-1] for x in test_path]\n",
    "val_label['label'] = predict(test_loader, model, 1).argmax(1)\n",
    "val_label.to_csv('submit.csv', index=None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "id": "5dc9d50b-9959-4cd7-acfb-91644ccddac6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ImageID</th>\n",
       "      <th>label</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>006f490b-c352-414c-be06-0e14a39eb3ee.jpg</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>007d7487-413d-4d11-9df1-1c40651f6428.jpg</td>\n",
       "      <td>15</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>00b15eef-38c6-42e0-b1ed-5bbd34d9f20f.jpg</td>\n",
       "      <td>18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>00d3d2ea-2f66-40b7-b402-b2bcd36cf776.jpg</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>01207b72-00c6-43c4-aa14-85e76c138022.jpg</td>\n",
       "      <td>53</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1820</th>\n",
       "      <td>ff3d0831-0110-4106-b76a-c9f5c8291a18.jpg</td>\n",
       "      <td>18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1821</th>\n",
       "      <td>ff5c00d4-91eb-4347-84c2-2824654eb625.jpg</td>\n",
       "      <td>25</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1822</th>\n",
       "      <td>ff74d365-3be6-49e9-878f-806e8c8b83de.jpg</td>\n",
       "      <td>34</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1823</th>\n",
       "      <td>ff864ef5-5cb2-4d63-a6d5-d6f8980f6f23.jpg</td>\n",
       "      <td>37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1824</th>\n",
       "      <td>fffe3a3d-d06b-4229-8140-2836232ae027.jpg</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1825 rows × 2 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                                       ImageID  label\n",
       "0     006f490b-c352-414c-be06-0e14a39eb3ee.jpg      5\n",
       "1     007d7487-413d-4d11-9df1-1c40651f6428.jpg     15\n",
       "2     00b15eef-38c6-42e0-b1ed-5bbd34d9f20f.jpg     18\n",
       "3     00d3d2ea-2f66-40b7-b402-b2bcd36cf776.jpg      1\n",
       "4     01207b72-00c6-43c4-aa14-85e76c138022.jpg     53\n",
       "...                                        ...    ...\n",
       "1820  ff3d0831-0110-4106-b76a-c9f5c8291a18.jpg     18\n",
       "1821  ff5c00d4-91eb-4347-84c2-2824654eb625.jpg     25\n",
       "1822  ff74d365-3be6-49e9-878f-806e8c8b83de.jpg     34\n",
       "1823  ff864ef5-5cb2-4d63-a6d5-d6f8980f6f23.jpg     37\n",
       "1824  fffe3a3d-d06b-4229-8140-2836232ae027.jpg      8\n",
       "\n",
       "[1825 rows x 2 columns]"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val_label"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f350b9a1-82a7-4051-8492-3dc762d8aaab",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py3.11",
   "language": "python",
   "name": "py3.11"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}